package com.jmu.content.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jmu.constant.MessageConstant;
import com.jmu.constant.StatusConstant;
import com.jmu.content.dto.OrdersPageDTO;
import com.jmu.content.dto.OrdersSubmitDTO;
import com.jmu.content.mapper.OrdersMapper;
import com.jmu.content.pojo.ChargePile;
import com.jmu.content.pojo.ChargeStation;
import com.jmu.content.pojo.Orders;
import com.jmu.content.pojo.PriceList;
import com.jmu.content.result.PageResult;
import com.jmu.content.result.Result;
import com.jmu.content.service.ChargePileService;
import com.jmu.content.service.ChargeStationService;
import com.jmu.content.service.OrdersService;
import com.jmu.content.service.PriceListService;
import com.jmu.content.vo.OrdersUserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author fems
 * @since 2024-05-06
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    PriceListService priceListService;

    @Autowired
    ChargePileService chargePileService;

    @Autowired
    ChargeStationService chargeStationService;

    @Override
    public void finishCharge(Long id) {
        Orders order = this.getById(id);
        LocalDateTime now = LocalDateTime.now();

        // 释放充电站
        LambdaUpdateWrapper<ChargePile> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ChargePile::getId,order.getPileId())
                .set(ChargePile::getIsLocked, StatusConstant.PILE_UNLOCKED);
        chargePileService.update(wrapper);

        // 获取单价
        BigDecimal price = getPrice(order, now);

        Duration between = Duration.between(order.getBeginTime(), now);
        price = price.multiply(new BigDecimal(between.toMinutes()));
        LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Orders::getId,id)
                .set(Orders::getEndTime,now)
                .set(Orders::getStatus,2)
                .set(Orders::getPayment,1)
                .set(Orders::getPower,10)
                .set(Orders::getAmount,price);
        this.update(updateWrapper);

    }

    private BigDecimal getPrice(Orders order, LocalDateTime now) {
        Long stationId = order.getStationId();
        LambdaQueryWrapper<PriceList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PriceList::getStationId,stationId);
        List<PriceList> priceLists = priceListService.list(queryWrapper);
        if (priceLists == null){
            return new BigDecimal(1.0);
        }
        BigDecimal price = new BigDecimal(0.0);
        for (PriceList priceList : priceLists) {
            if (priceList.getBeginTime().compareTo(now.toLocalTime())<0){
                price = priceList.getPrice();
                break;
            }
        }
        return price;
    }

    @Override
    public OrdersUserVO orderBegin(OrdersSubmitDTO ordersSubmitDTO) {
        Orders orders = new Orders();
        orders.setPileId(ordersSubmitDTO.getPileId());
        ChargePile chargePile = chargePileService.getById(ordersSubmitDTO.getPileId());
        ChargeStation station = chargeStationService.getById(ordersSubmitDTO.getStationId());
        if (chargePile == null || station == null){
            return null;
        }
        // 锁定充电站
        LambdaUpdateWrapper<ChargePile> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ChargePile::getId,ordersSubmitDTO.getPileId())
                .set(ChargePile::getIsLocked, StatusConstant.PILE_LOCKED);
        chargePileService.update(updateWrapper);

        orders.setUserId(ordersSubmitDTO.getUserId());
        orders.setStationId(ordersSubmitDTO.getStationId());
        orders.setStatus(0);
        orders.setBeginTime(LocalDateTime.now());
        this.save(orders);
        OrdersUserVO vo = new OrdersUserVO();
        BeanUtils.copyProperties(orders,vo);
        vo.setPrice(getPrice(orders,orders.getBeginTime()));
        return vo;
    }

    @Override
    public PageResult pageQuery(OrdersPageDTO dto) {

        Page<Orders> page = PageHelper.startPage(dto.getPage(), dto.getPageSize());
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(dto.getStatus()!=null,Orders::getStatus,dto.getStatus());
        queryWrapper.ge(dto.getBeginTime()!=null,Orders::getBeginTime,dto.getBeginTime())
                .le(dto.getEndTime()!=null,Orders::getEndTime,dto.getEndTime());
        List<Orders> list = this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo(list);

        return new PageResult(page.getTotal(),pageInfo.getList());

    }

    @Override
    public List<OrdersUserVO> listBatchPile(Long currentId) {
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId,currentId);

        List<Orders> list = this.list(queryWrapper);
        List<OrdersUserVO> collect = list.stream().map(item -> {
            OrdersUserVO vo = new OrdersUserVO();
            BeanUtils.copyProperties(item, vo);
            Long pileId = item.getPileId();
            Long stationId = item.getStationId();
            ChargeStation station = chargeStationService.getById(stationId);
            ChargePile chargePile = chargePileService.getById(pileId);
            // 获取单价
            BigDecimal price = getPrice(item, item.getBeginTime());
            vo.setStationName(station.getName());
            vo.setVoltage(chargePile.getVoltage());
            vo.setPrice(price);
            vo.setCurrent(chargePile.getCurrent());
            vo.setMaxPower(chargePile.getMaxPower());
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }
}
